package com.cmcc.pcap.voltePcapParse;

import com.cmcc.pcap.voltePcapParse.pcap.*;
import com.cmcc.pcap.voltePcapParse.utils.pcap.DataUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Pcap 文件解析工具类
 * @author starfish
 *
 */
public class PcapParser {

	private PcapFileStruct pcapFileStruct;
	private ProtocolData protocolData;
	private EthernetHeader ethernetHeader;
	private VirtualLanEntity virtualLan;
	private IPHeader ipHeader;
	private TCPHeader tcpHeader;
	private UDPHeader udpHeader;
	private SCTPHeader sctpHeader;
	private String loadContent;//负载信息
	private LoadData loadData;
	
	private byte[] file_header = new byte[24];
	private byte[] data_header = new byte[16];
	private byte[] content;
//	private byte[] ip_content;
//	private byte[] tcp_content;
//	private byte[] udp_content;
	
	private int data_offset = 0;			// 数据负载信息所在开始位置
//	private byte[] data_content;			// 数据包的数据负载
	
	private static final Logger logger = LoggerFactory.getLogger(PcapParser.class);
	
	public static void main(String[] args) {
		PcapParser pcapParser = new PcapParser();
		pcapParser.getHeaderMap("sipcalltrue00000574666b9ccec29fe","diameter000000005743b5879abc2515","/files/pcap/");
//		pcapParser.parse("gtpsv00000000000574666b8f1006f8d", "gtpsv00000000000574666b8f1006f8d","/files/pcap/");
		
	}

	public PcapFileStruct parse (String xdrId,String defaultXdrId,String xdrPath) {
		pcapFileStruct = new PcapFileStruct();
		List<PcapMsgStruct> pcapMsgStructs = new ArrayList<PcapMsgStruct>();
		String directory = PcapParser.class.getResource(xdrPath).getFile();
		//判断xdr.pcap文件是否存在
		
		File pcapFile = new File(directory + xdrId + ".pcap");
		if(!pcapFile.exists()){
			pcapFile = new File(directory + defaultXdrId + ".pcap");
		}
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(pcapFile);
			int m = fis.read(file_header);
			if (m > 0) {

				PcapFileHeader fileHeader = parseFileHeader(file_header);

				pcapFileStruct.setFileHeader(fileHeader);
				
				m = fis.read(data_header);
				while (m > 0) {
					PcapMsgStruct pcapMsgStruct = new PcapMsgStruct();
					PcapDataHeader pcapDataHeader = parseDataHeader(data_header);

					content = new byte[pcapDataHeader.getCaplen()];
					m = fis.read(content);
					
					protocolData = new ProtocolData();

					// 1. 读取以太网数据帧
					ethernetHeader = readEthernetHeader(content);//读取前14个字节
//					int   vlanOffset = 4;
					// 2. 读取 IP
					ipHeader = readIPHeader(content);//读取接下来的20个字节

					int offset = 14;							// 以太网数据帧长度（数据链路包头）
					offset += 20;                               // IP层包头长度

					// 3. 根据 protocol 类型进行分析,TCP或UDP读取再接下来的20个字节
					ProtocolType protocol = ipHeader.getProtocol();
					if (ProtocolType.TCP.getType().equals(protocol.getType())) {
						protocolData.setProtocolType(ProtocolType.TCP);
						tcpHeader = readTCPHeader(content, offset);
					} else if (ProtocolType.UDP.getType().equals(protocol.getType())) {
						protocolData.setProtocolType(ProtocolType.UDP);
						udpHeader = readUDPHeader(content);
					} else if (ProtocolType.SCTP.getType().equals(protocol.getType())) {
						protocolData.setProtocolType(ProtocolType.SCTP);
						sctpHeader = readSCTPHeader(content);
					} else {
//						LogUtils.printObj("这是其他协议的数据包");
					}
					
					if(protocolData.getProtocolType() != ProtocolType.OTHER){
						/*
						 * 数据负载信息
						 */
//						int data_size = content.length - data_offset;
////						LogUtils.printObj("数据负载长", data_size);
//						data_content = new byte[data_size];
//						for (int i = 0; i < data_size; i ++) {
//							data_content[i] = content[i + data_offset];
//						}
//						
//						loadContent = new String(content);
						loadData = readLoadData(content);
						
					}
					pcapMsgStruct.setPcapDataHeader(pcapDataHeader);
					pcapMsgStruct.setEthernetHeader(ethernetHeader);
					pcapMsgStruct.setProtocolData(protocolData);
					pcapMsgStruct.setIpHeader(ipHeader);
					pcapMsgStruct.setTcpHeader(tcpHeader);
					pcapMsgStruct.setUdpHeader(udpHeader);
					pcapMsgStruct.setLoadContent(loadContent);
					pcapMsgStruct.setLoadData(loadData);
					pcapMsgStructs.add(pcapMsgStruct);
					m = fis.read(data_header);
				}
				pcapFileStruct.setPcapMsgStructs(pcapMsgStructs);
			}
		} catch (Exception e) {
			logger.error("读取以太网数据出错",e);
			e.printStackTrace();
		} finally {
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					logger.error("读取以太网数据出错",e);
					e.printStackTrace();
				}
			}
		}
		return pcapFileStruct;
	}
	
	public VirtualLanEntity readVirtualLan(EthernetHeader ethernetHeader,byte[] content){
		VirtualLanEntity entity = new VirtualLanEntity();
		int offset = data_offset;
		if(ethernetHeader.getFrameType().equals("802.1Q Virtual LAN")){
			byte pri = content[offset];
			pri = (byte) ((pri>>>5) & 0xff);
			entity.setPri(pri);
			
			byte dei = content[offset];
			dei = (byte) ((((dei<<3) & 0xff)>>7) & 0xff);  
			entity.setDei(dei);
			
			byte id1 = content[offset];
			id1 = (byte) ((((id1<<4) & 0xff)>>4) & 0xff);
			offset ++;
			byte id2 = content[offset];
			byte[] idbytes = new byte[]{id1,id2};
//			System.out.println(Integer.toBinaryString(id1));
//			System.out.println(Integer.toBinaryString(id2));
			String id = new BigInteger(1,idbytes).toString(10);
			entity.setId(new Short(id));
			offset ++;
			byte[] buff_2 = new byte[2];
			for (int i = 0; i < 2; i ++) {
				buff_2[i] = content[i + offset];
			}
			
			entity.setType(DataUtils.bytesToHexString(buff_2));
			offset = offset + 2;
			data_offset = offset;
			
			return entity;
			
		}
		return null;
	}

	public Map<String,Map<String,String>> getHeaderMap (String xdrId,String defaultXdrId,String xdrPath) {
		
		Map<String,Map<String,String>> headerMaps =new  LinkedHashMap <String,Map<String,String>>();
		String directory = PcapParser.class.getResource(xdrPath).getFile();
		//判断xdr.pcap文件是否存在
		
		File pcapFile = new File(directory + xdrId + ".pcap");
		if(!pcapFile.exists()){
			pcapFile = new File(directory + defaultXdrId + ".pcap");
		}
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(pcapFile);
			int m = fis.read(file_header);
			if (m > 0) {
				m = fis.read(data_header);
				int i=0;
				while (m > 0) {
					i++;
//					PcapMsgStruct pcapMsgStruct = new PcapMsgStruct();
					PcapDataHeader pcapDataHeader = parseDataHeader(data_header);
					content = new byte[pcapDataHeader.getCaplen()];
					m = fis.read(content);
					protocolData = new ProtocolData();
					// 1. 读取以太网数据帧
					ethernetHeader = readEthernetHeader(content);//读取前14个字节
					
					virtualLan = readVirtualLan(ethernetHeader,content);

					// 2. 读取 IP
					ipHeader = readIPHeader(content);//读取接下来的20个字节
					int offset = 14;							// 以太网数据帧长度（数据链路包头）
					offset += 20;                               // IP层包头长度
					// 3. 根据 protocol 类型进行分析,TCP或UDP读取再接下来的20个字节
					ProtocolType protocol = ipHeader.getProtocol();
					if (ProtocolType.TCP.getType().equals(protocol.getType())) {
						protocolData.setProtocolType(ProtocolType.TCP);
						tcpHeader = readTCPHeader(content, offset);
					} else if (ProtocolType.UDP.getType().equals(protocol.getType())) {
						protocolData.setProtocolType(ProtocolType.UDP);
						udpHeader = readUDPHeader(content);
					} else if (ProtocolType.SCTP.getType().equals(protocol.getType())) {
						protocolData.setProtocolType(ProtocolType.SCTP);
						sctpHeader = readSCTPHeader(content);
					} else {
//						LogUtils.printObj("这是其他协议的数据包");
					}
					
//					  数据负载信息
					loadData = readLoadData(content);
					m = fis.read(data_header);
					Map<String,String> headerMap = new LinkedHashMap <String,String>();
					headerMap.put("ethernetHeader", ethernetHeader.toString());
					headerMap.put("virtualLan", virtualLan == null? null:virtualLan.toString());
					headerMap.put("ipHeader", ipHeader.toString());
					if(ProtocolType.SCTP.getType().equals(protocol.getType())){
						headerMap.put("protocolHeader", sctpHeader.toString());
					}
					if(ProtocolType.UDP.getType().equals(protocol.getType())){
						headerMap.put("protocolHeader", udpHeader.toString());
					}
					headerMap.put("loadData", loadData.toString());
					headerMaps.put(Integer.toString(i), headerMap);
				}
			}
		} catch (Exception e) {
			logger.error("读取以太网数据出错",e);
			e.printStackTrace();
		} finally {
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					logger.error("读取以太网数据出错",e);
					e.printStackTrace();
				}
			}
		}
		return headerMaps;
	}
	
	/**
	 * 负载数据,offset = 42
	 * @param content
	 * @return
	 */
	private LoadData readLoadData(byte[] content) {
		//偏移量就是程序的逻辑地址与段首的差值,IPHeader的起始偏移量为14
		int offset = data_offset ; //42;
		LoadData loadData = new LoadData();
		// 此字段的offset为54,使用之后offset = content.length
		String data = "";
		//定义一个行数n
		int n=0;
		for(int i = 0;i < content.length-offset; i++){
			if(data.contains("</br>")){
				//16个字节换行,且需要减去</br>字符的长度 
				if(DataUtils.isNumeric(((float)data.length()-5*n)/47)){
					data=data+"</br>";
					n++;
				}
			}else{
				//首行字符判断16个字节开始换行
				if(DataUtils.isNumeric((float)data.length()/47)){
					data=data+"</br>";
					n++;
				}
			}
			byte buff_0  = content[i + offset];
			if(i>0){
				//换行开始不加空格
				if(data.endsWith("</br>")){
					if(DataUtils.byteToHexString(buff_0).length()>1 ){
						data = data+DataUtils.byteToHexString(buff_0 );
					}else{
						data = data+"0"+DataUtils.byteToHexString(buff_0 );
					}
				}else{
					if(DataUtils.byteToHexString(buff_0).length()>1 ){
						data = data+" "+DataUtils.byteToHexString(buff_0 );
					}else{
						data = data+" 0"+DataUtils.byteToHexString(buff_0 );
					}
				}
				
			}else{
				//首行开始不加空格
				if(DataUtils.byteToHexString(buff_0).length()>1){
					data = DataUtils.byteToHexString(buff_0 );
				}else{
					data = "0"+DataUtils.byteToHexString(buff_0 );
				}
			}
		}
		loadData.setLength(content.length);
		loadData.setData(data);
		return loadData;
	}
	/**
	 * 读取 pcap 文件头,共24字节
	 */
	public PcapFileHeader parseFileHeader(byte[] file_header) throws IOException {
		PcapFileHeader fileHeader = new PcapFileHeader();
		byte[] buff_4 = new byte[4];	// 4 字节的数组
		byte[] buff_2 = new byte[2];	// 2 字节的数组

		int offset = 0;
		for (int i = 0; i < 4; i ++) {                     // 取得偏移量0、1、2、3的字节数据
			buff_4[i] = file_header[i + offset];
		}
		offset += 4;                                       // offset = 4
		int magic = DataUtils.byteArrayToInt(buff_4);
		fileHeader.setMagic(magic);

		for (int i = 0; i < 2; i ++) {                     // 取得偏移量4、5的字节数据
			buff_2[i] = file_header[i + offset];
		}
		offset += 2;                                       // offset = 6
		short magorVersion = DataUtils.byteArrayToShort(buff_2);
		fileHeader.setMagorVersion(magorVersion);

		for (int i = 0; i < 2; i ++) {                     // 取得偏移量6、7的字节数据
			buff_2[i] = file_header[i + offset];
		}
		offset += 2;                                       // offset = 8
		short minorVersion = DataUtils.byteArrayToShort(buff_2);
		fileHeader.setMinorVersion(minorVersion);

		for (int i = 0; i < 4; i ++) {                     // 取得偏移量8、9、10、11的字节数据
			buff_4[i] = file_header[i + offset];
		}
		offset += 4;                                       // offset = 12
		int timezone = DataUtils.byteArrayToInt(buff_4);
		fileHeader.setTimezone(timezone);

		for (int i = 0; i < 4; i ++) {                     // 取得偏移量12、13、14、15的字节数据
			buff_4[i] = file_header[i + offset];
		}
		offset += 4;                                       // offset = 16
		int sigflags = DataUtils.byteArrayToInt(buff_4);
		fileHeader.setSigflags(sigflags);

		for (int i = 0; i < 4; i ++) {                     // 取得偏移量16、17、18、19的字节数据
			buff_4[i] = file_header[i + offset];
		}
		offset += 4;                                       // offset = 20
		int snaplen = DataUtils.byteArrayToInt(buff_4);
		fileHeader.setSnaplen(snaplen);

		for (int i = 0; i < 4; i ++) {                     // 取得偏移量20、21、22、23的字节数据
			buff_4[i] = file_header[i + offset];
		}
		offset += 4;                                       // 24
		int linktype = DataUtils.byteArrayToInt(buff_4);
		fileHeader.setLinktype(linktype);

		return fileHeader;
	}

	/**
	 * 读取数据包头，共16字节
	 */
	public PcapDataHeader parseDataHeader(byte[] data_header){
		byte[] buff_4 = new byte[4];
		PcapDataHeader dataHeader = new PcapDataHeader();
		int offset = 0;                                  // 取得偏移量为0、1、2、3的字节数据
		for (int i = 0; i < 4; i ++) {
			buff_4[i] = data_header[i + offset];
		}
		offset += 4;                                     // offset = 4
		int timeS = DataUtils.byteArrayToInt(buff_4);
		dataHeader.setTimeS(timeS);

		for (int i = 0; i < 4; i ++) {                   // 取得偏移量4、5、6、7的字节数据
			buff_4[i] = data_header[i + offset];
		}
		offset += 4;                                     // offset = 8
		int timeMs = DataUtils.byteArrayToInt(buff_4);
		dataHeader.setTimeMs(timeMs);

		for (int i = 0; i < 4; i ++) {                   // 取得偏移量8、9、10、11的字节数据
			buff_4[i] = data_header[i + offset];
		}
		offset += 4;                                     // offset = 12
		// 得先逆序在转为 int
		DataUtils.reverseByteArray(buff_4);
		int caplen = DataUtils.byteArrayToInt(buff_4);
		dataHeader.setCaplen(caplen);
//		LogUtils.printObj("数据包实际长度", dataHeader.getCaplen());

		for (int i = 0; i < 4; i ++) {                   // 取得偏移量12、13、14、15的字节数据
			buff_4[i] = data_header[i + offset];
		}
		offset += 4;                                     // offset = 16
		//		int len = DataUtils.byteArrayToInt(buff_4);
		DataUtils.reverseByteArray(buff_4);
		int len = DataUtils.byteArrayToInt(buff_4);
		dataHeader.setLen(len);

		return dataHeader;
	}

	/**
	 * TCP/UDP包头  ：20字节,offset＝34
	 * @param content2
	 * @param offset
	 * @return
	 */
	private TCPHeader readTCPHeader(byte[] content2, int offset) {
		byte[] buff_2 = new byte[2];
		byte[] buff_4 = new byte[4];

		TCPHeader tcp = new TCPHeader();

		for (int i = 0; i < 2; i ++) {				// 取得偏移量为35、36的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 36
		short srcPort = DataUtils.byteArrayToShort(buff_2);
		tcp.setSrcPort(srcPort);

		String sourcePort = validateData(srcPort);
		protocolData.setSrcPort(sourcePort);

		for (int i = 0; i < 2; i ++) {                  // 取得偏移量为 36、37的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 38
		short dstPort = DataUtils.byteArrayToShort(buff_2);
		tcp.setDstPort(dstPort);

		String desPort = validateData(dstPort);
		protocolData.setDesPort(desPort);

		for (int i = 0; i < 4; i ++) {                  // 取得偏移量为 39、40、41、42的字节数据
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// offset = 42
		int seqNum = DataUtils.byteArrayToInt(buff_4);
		tcp.setSeqNum(seqNum);

		for (int i = 0; i < 4; i ++) {                  // 取得偏移量为42、 43、44、45的字节数据
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// offset = 46
		int ackNum = DataUtils.byteArrayToInt(buff_4);
		tcp.setAckNum(ackNum);

		byte headerLen = content[offset ++];			// 取得偏移量为46的字节数据， offset = 47
		tcp.setHeaderLen(headerLen);

		byte flags = content[offset ++];				// 取得偏移量为47的字节数据， offset = 48
		tcp.setFlags(flags);

		for (int i = 0; i < 2; i ++) {                 // 取得偏移量为48、49的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 50
		short window = DataUtils.byteArrayToShort(buff_2);
		tcp.setWindow(window);

		for (int i = 0; i < 2; i ++) {                  // 取得偏移量为50、51的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 52
		short checkSum = DataUtils.byteArrayToShort(buff_2);
		tcp.setCheckSum(checkSum);

		for (int i = 0; i < 2; i ++) {                  // 取得偏移量为52、53的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 54
		short urgentPointer = DataUtils.byteArrayToShort(buff_2);
		tcp.setUrgentPointer(urgentPointer);
		data_offset = offset;
		return tcp;
	}

	/**
	 * TCP/UDP包头  ：20字节,offset＝34
	 * @param content2
	 * @param offset
	 * @return
	 */
	private SCTPHeader readSCTPHeader(byte[] content) {
		int offset = data_offset;
		byte[] buff_2 = new byte[2];
		byte[] buff_4 = new byte[4];

		SCTPHeader sctp = new SCTPHeader();
		SCTPDataChunk chunk = new SCTPDataChunk();

		for (int i = 0; i < 2; i ++) {				// 取得偏移量为35、36的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 36
		short srcPort = DataUtils.byteArrayToShort(buff_2);
		sctp.setSrcPort(srcPort);

		String sourcePort = validateData(srcPort);
		protocolData.setSrcPort(sourcePort);

		for (int i = 0; i < 2; i ++) {                  // 取得偏移量为 36、37的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 38
		short dstPort = DataUtils.byteArrayToShort(buff_2);
		sctp.setDstPort(dstPort);

		String desPort = validateData(dstPort);
		protocolData.setDesPort(desPort);

		for (int i = 0; i < 4; i ++) {                  // 取得偏移量为 39、40、41、42的字节数据
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// offset = 42
		sctp.setVerification("0x"+DataUtils.binary(buff_4, 16));

		for (int i = 0; i < 4; i ++) {                  // 取得偏移量为42、 43、44、45的字节数据
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// offset = 46
		sctp.setCheckSum("0x"+DataUtils.binary(buff_4,16));
		
		byte chunkType = content[offset ++];					 
		chunk.setChunkType(DataUtils.byteToHexString(chunkType));
		byte chunkFlags = content[offset ++];					  
		chunk.setChunkFlags(DataUtils.byteToHexString2(chunkFlags));
		for (int i = 0; i < 2; i ++) {                  // 取得偏移量为 36、37的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 38
		int chunkLength = DataUtils.byteArrayToShort(buff_2);
		chunk.setChunkLength( chunkLength );
		
		for (int i = 0; i < 4; i ++) {                  // 取得偏移量为 36、37的字节数据
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// offset = 38
		String tsn = DataUtils.binary(buff_4,10);
		chunk.setTsn(tsn);
		
		for (int i = 0; i < 2; i ++) {                  // 取得偏移量为 36、37的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 38
		Short sid = DataUtils.byteArrayToShort(buff_2);
		String sids=DataUtils.shortToHexString4(sid);
		chunk.setSid(sids);
		
		for (int i = 0; i < 2; i ++) {                  // 取得偏移量为 36、37的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 38
		String ssn = DataUtils.binary(buff_2,10);
		chunk.setSsn(ssn);
		
		for (int i = 0; i < 4; i ++) {                  // 取得偏移量为 36、37的字节数据
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// offset = 38
		String ppid = DataUtils.binary(buff_4,10);
		chunk.setPpid(ppid);
		
		sctp.setSctpDATAchunk(chunk);
		data_offset = offset;
		return sctp;
	}

	/**
	 * TCP/UDP包头  ：20字节,offset＝34  ,是否包含vlan ,包含则跳转4个字节
	 */
	private UDPHeader readUDPHeader(byte[] content) {
		int offset= data_offset;
		byte[] buff_2 = new byte[2];

		UDPHeader udp = new UDPHeader();
		
		for (int i = 0; i < 2; i ++) {                 // 提取偏移量为34、35的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 36
		String srcPort = DataUtils.binary(buff_2, 10);
		udp.setSrcPort(srcPort);
		protocolData.setSrcPort(srcPort);

		for (int i = 0; i < 2; i ++) {                  // 提取偏移量为 36、37的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 38
		String dstPort = DataUtils.binary(buff_2, 10);
		udp.setDstPort(dstPort);
		protocolData.setDesPort(dstPort);

		for (int i = 0; i < 2; i ++) {                  // 提取偏移量为 38、39的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 40
		short length = DataUtils.byteArrayToShort(buff_2);
		udp.setLength(length);

		for (int i = 0; i < 2; i ++) {                  // 提取偏移量为 40、41的字节数据
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// offset = 42
		String checkSum = DataUtils.binary(buff_2,16);
		udp.setCheckSum(DataUtils.stringToHex(checkSum));
		
		data_offset = offset;

		return udp;
	}

	/**
	 * 读取 Pcap 数据帧（数据链路头14字节）,offset = 0
	 * @param fis
	 */
	public EthernetHeader readEthernetHeader(byte[] content) {
		EthernetHeader dataFrame = new EthernetHeader();
		int offset = 0;
		byte[] buff_0 = new byte[6];                 //取取偏移量offset为0、1、2、3、4、5的字节数据
		for(int i = 0;i < 6; i++){
			buff_0[i] = content[i + offset];
		}
		String desMacStr = "";
		for(int i = 0;i < buff_0.length; i++){
			String sTemp = Integer.toHexString(0xFF &  buff_0[i]);
			if(sTemp.length() < 2){
				sTemp = "0" + sTemp;
			}
			desMacStr = desMacStr + sTemp+":";
		}
		    
		desMacStr = desMacStr.substring(0,desMacStr.lastIndexOf(":"));
		dataFrame.setDesMac(desMacStr);
		
		offset = 6;
		byte[] buff_1 = new byte[6];              //取得偏移量offset为6、7、8、9、10、11的字节数据
		for(int i = 0;i < 6; i++){
			buff_1[i] = content[i + offset];
		}
		
		String srcMacStr = "";
		for(int i = 0;i < buff_1.length; i++){
			String sTemp = Integer.toHexString(0xFF &  buff_1[i]);
			if(sTemp.length() < 2){
				sTemp = "0" + sTemp;
			}
			srcMacStr = srcMacStr + sTemp+":";
		}

		srcMacStr = srcMacStr.substring(0,srcMacStr.lastIndexOf(":"));
		dataFrame.setSrcMac(srcMacStr);
		
		offset = 12;
		byte[] buff_2 = new byte[2];              //取得偏移量offset为12、13的数据
		for (int i = 0; i < 2; i ++) {
			buff_2[i] = content[i + offset];
		}
		offset+=2;
		String frameType = DataUtils.bytesToHexString(buff_2);
		dataFrame.setFrameType(FrameType.getName(frameType));
//		if(frameType.equals("0x8100")){
//			offset+=4;
//		}
		data_offset = offset;
		return dataFrame;
	}

	/**
	 * IP头,offset = 14
	 * @param content
	 * @return
	 */
	private IPHeader readIPHeader(byte[] content) {
		//偏移量就是程序的逻辑地址与段首的差值,IPHeader的起始偏移量为14
		int offset=data_offset;
//		int offset = 14+vlanOffset;
		IPHeader ip = new IPHeader();

		byte[] buff_2 = new byte[2];
		byte[] buff_4 = new byte[4];
		
		// 1 byte
		byte varHLen = content[offset ++];				// 此字段的offset为14,使用之后offset = 15
		if (varHLen == 0) { 
			return null;
		}
		ip.setVarHLen(DataUtils.byteToHexString(varHLen));
		
		// 1 byte
		byte tos = content[offset ++];					// 此字段的offset为15,使用之后offset = 16
		ip.setTos(DataUtils.byteToHexString2(tos));
		
		// 2 byte                                       // 此处取得offset为16、17的值
		for (int i = 0; i < 2; i ++) {		
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// 使用之后offset = 18
		short totalLen = DataUtils.byteArrayToShort(buff_2);
		ip.setTotalLen(totalLen);

		// 2 byte                                       // 此处取得offset为18,19的值
		for (int i = 0; i < 2; i ++) {			
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// 使用之后offset = 20
		short id = DataUtils.byteArrayToShort(buff_2);
		ip.setId(DataUtils.shortToHexString4(id) + "(" + DataUtils.binary(buff_2,10) + ")");
		// 2 byte                                       // 此处取得offset为20、21的值
		for (int i = 0; i < 2; i ++) {					
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// 使用之后offset = 22
		short flagSegment = DataUtils.byteArrayToShort(buff_2);
		//此字段展示时需要拆分成flag和segment
		ip.setFlagSegment(flagSegment);

		// 1 byte
		byte ttl = content[offset ++];
		// 此处取得offset为22的值，使用之后offset = 23
//		String s = DataUtils.byteToHexString(ttl);
		int x = Integer.parseInt(DataUtils.byteToHexString(ttl),16);
		ip.setTtl(x);

		// 1 byte
		byte protocol = content[offset ++];				// 此处取得offset为23的值，使用之后offset = 24
		int type = DataUtils.byteToInt(protocol);
		ip.setProtocol(ProtocolType.getProtocolType(Integer.toString(type)));

		// 2 byte                                       // 此处取得offset为24、25的值
		for (int i = 0; i < 2; i ++) {					
			buff_2[i] = content[i + offset];
		}
		offset += 2;									// 使用之后offset = 26
		short checkSum = DataUtils.byteArrayToShort(buff_2);
		ip.setCheckSum(DataUtils.shortToHexString4(checkSum));

		// 4 byte                                      // 此处取得offset为26、27、28、29的值
		for (int i = 0; i < 4; i ++) {					
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// 使用之后offset = 30
		try {
			String srcIp = InetAddress.getByAddress(buff_4).getHostAddress();
			ip.setSrcIP(srcIp);
		} catch (UnknownHostException e) {
			logger.error("获取主机IP地址出错：",e);
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 拼接出 SourceIP
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < 4; i++) {
			builder.append((int) (buff_4[i] & 0xff));
			builder.append(".");
		}
		builder.deleteCharAt(builder.length() - 1);
		String sourceIP = builder.toString();
		protocolData.setSrcIP(sourceIP);

		// 4 byte                                      // 此处取得offset为30、31、32、33的值
		for (int i = 0; i < 4; i ++) {		
			buff_4[i] = content[i + offset];
		}
		offset += 4;									// offset = 34
		try {
			String dstIp = InetAddress.getByAddress(buff_4).getHostAddress();
			ip.setDstIP(dstIp);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			logger.error("获取主机IP地址出错：",e);
			e.printStackTrace();
		}

		// 拼接出 DestinationIP
		builder = new StringBuilder();
		for (int i = 0; i < 4; i++) {
			builder.append((int) (buff_4[i] & 0xff));
			builder.append(".");
		}
		builder.deleteCharAt(builder.length() - 1);
		String destinationIP = builder.toString();
		protocolData.setDesIP(destinationIP);
		data_offset=offset;
		return ip;
	}

	/**
	 * 修正端口号为负值的导致转换为十进制数据出错
	 * @param data
	 * @return
	 */
	private String validateData (int data) {
		String rs = data + "";
		if (data < 0) {
			String binaryPort = Integer.toBinaryString(data);
			rs = DataUtils.binaryToDecimal(binaryPort) + "";
		}
		return rs;
	}
	
}
